home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Id: IORawSerial.cpp 1.3 1995/09/26 19:45:11 olsen Exp olsen $
- **
- ** :ts=4
- */
-
- /*
- * Copyright © 1995 by Olaf Barthel, All Rights Reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This software has not been validated by the ``Bundesamt fuer Zulassungen in
- * der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
- * must not be used for accessing the BTX-Network of the Telekom in Germany.
- *
- * Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
- * der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
- * am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
- */
-
- #include "IORawSerial.hpp"
-
- #include <exec/memory.h>
- #include <exec/errors.h>
-
- #include <devices/serial.h>
- #include <devices/timer.h>
-
- #include <hardware/cia.h>
-
- #include <clib/exec_protos.h>
-
- #ifdef __SASC
- #include <pragmas/exec_pragmas.h>
-
- extern struct ExecBase *SysBase;
- #endif // _SASC
-
- #include <string.h>
- #include <stdio.h>
-
- VOID IORawSerial::StopRead(VOID)
- {
- if(Valid && Reading)
- {
- if(!CheckIO((struct IORequest *)ReadRequest))
- AbortIO((struct IORequest *)ReadRequest);
-
- WaitIO((struct IORequest *)ReadRequest);
-
- Reading = FALSE;
- }
- }
-
- VOID IORawSerial::StartRead(VOID)
- {
- if(Valid)
- {
- StopRead();
-
- ReadRequest->IOSer.io_Command = CMD_READ;
- ReadRequest->IOSer.io_Data = &SingleChar;
- ReadRequest->IOSer.io_Length = 1;
-
- SetSignal(0,ReadMask);
-
- SendIO((struct IORequest *)ReadRequest);
-
- Reading = TRUE;
- }
- }
-
- BYTE IORawSerial::WaitRead(VOID)
- {
- BYTE Error;
-
- if(Valid)
- {
- if(Reading)
- {
- Error = WaitIO((struct IORequest *)ReadRequest);
-
- Reading = FALSE;
- }
- else
- Error = 0;
- }
- else
- Error = IOERR_OPENFAIL;
-
- return(Error);
- }
-
- VOID IORawSerial::Close(VOID)
- {
- if(Valid)
- {
- StopRead();
- StopTime();
-
- CloseDevice((struct IORequest *)TimeRequest);
-
- DeleteIORequest((struct IORequest *)TimeRequest);
-
- DeleteMsgPort(TimePort);
-
- CloseDevice((struct IORequest *)ReadRequest);
-
- DeleteIORequest((struct IORequest *)ReadRequest);
-
- FreeVec(WriteRequest);
-
- DeleteMsgPort(WritePort);
-
- DeleteMsgPort(ReadPort);
-
- Valid = FALSE;
- }
- }
-
- LONG IORawSerial::Open(CONST STRPTR Channel,ULONG Unit,ULONG Baud,BOOL RTS_CTS)
- {
- if(ReadPort = CreateMsgPort())
- {
- ReadMask = 1UL << ReadPort->mp_SigBit;
-
- if(WritePort = CreateMsgPort())
- {
- if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
- {
- if(WriteRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
- {
- if(!OpenDevice((UBYTE *)Channel,Unit,(struct IORequest *)ReadRequest,NULL))
- {
- ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
- ReadRequest->io_ExtFlags = 0;
- ReadRequest->io_ReadLen = 8;
- ReadRequest->io_WriteLen = 8;
- ReadRequest->io_StopBits = 1;
-
- if(Baud)
- ReadRequest->io_Baud = Baud;
-
- if(RTS_CTS >= FALSE)
- {
- if(RTS_CTS)
- ReadRequest->io_SerFlags = (UBYTE)( ReadRequest->io_SerFlags | SERF_XDISABLED | SERF_7WIRE);
- else
- ReadRequest->io_SerFlags = (UBYTE)((ReadRequest->io_SerFlags | SERF_XDISABLED) & ~SERF_7WIRE);
- }
- else
- ReadRequest->io_SerFlags |= SERF_XDISABLED;
-
- if(!DoIO((struct IORequest *)ReadRequest))
- {
- CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
-
- WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
-
- if(TimePort = CreateMsgPort())
- {
- TimeMask = 1UL << TimePort->mp_SigBit;
-
- if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest)))
- {
- if(!OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
- {
- Valid = TRUE;
-
- StartRead();
-
- return(0);
- }
-
- DeleteIORequest((struct IORequest *)TimeRequest);
- TimeRequest = NULL;
- }
-
- DeleteMsgPort(TimePort);
- TimePort = NULL;
- }
- }
-
- CloseDevice((struct IORequest *)ReadRequest);
- }
-
- FreeVec(WriteRequest);
- WriteRequest = NULL;
- }
-
- DeleteIORequest((struct IORequest *)ReadRequest);
- ReadRequest = NULL;
- }
-
- DeleteMsgPort(WritePort);
- WritePort = NULL;
- }
-
- DeleteMsgPort(ReadPort);
- ReadPort = NULL;
- }
-
- return(-1);
- }
-
- LONG IORawSerial::GetChar(LONG Timeout)
- {
- LONG Result;
-
- if(Valid)
- {
- if(Reading)
- {
- if(CheckIO((struct IORequest *)ReadRequest))
- {
- if(WaitRead())
- Result = CHANNELERR_Nothing;
- else
- Result = SingleChar;
-
- StartRead();
- }
- else
- {
- if(Timeout)
- {
- ULONG Signals;
-
- StartTime(Timeout);
-
- for(;;)
- {
- Signals = ::Wait(ReadMask | TimeMask);
-
- if(Signals & ReadMask)
- {
- if(WaitRead())
- Result = CHANNELERR_Nothing;
- else
- Result = SingleChar;
-
- StopTime();
-
- StartRead();
-
- break;
- }
-
- if(Signals & TimeMask)
- {
- WaitTime();
-
- Result = CHANNELERR_Timeout;
-
- break;
- }
- }
- }
- else
- Result = CHANNELERR_Nothing;
- }
- }
- else
- Result = CHANNELERR_Nothing;
- }
- else
- Result = CHANNELERR_EOF;
-
- return(Result);
- }
-
- VOID IORawSerial::PutString(CONST STRPTR String,LONG Len)
- {
- if(Valid)
- {
- if(Len < 0)
- Len = strlen(String);
-
- WriteRequest->IOSer.io_Command = CMD_WRITE;
- WriteRequest->IOSer.io_Data = (APTR)String;
- WriteRequest->IOSer.io_Length = Len;
-
- DoIO((struct IORequest *)WriteRequest);
- }
- }
-
- LONG IORawSerial::Waiting(VOID)
- {
- if(Valid)
- {
- if(Reading)
- {
- if(CheckIO((struct IORequest *)ReadRequest))
- return(1);
- }
-
- WriteRequest->IOSer.io_Command = SDCMD_QUERY;
-
- DoIO((struct IORequest *)WriteRequest);
-
- return((LONG)WriteRequest->IOSer.io_Actual);
- }
- else
- return(0);
- }
-
- ULONG IORawSerial::WaitMask(VOID)
- {
- return(ReadMask);
- }
-
- VOID IORawSerial::Wait(LONG Seconds)
- {
- TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
- TimeRequest->tr_time.tv_secs = Seconds;
- TimeRequest->tr_time.tv_micro = 0;
-
- DoIO((struct IORequest *)TimeRequest);
- }
-
- IORawSerial::IORawSerial()
- {
- Reading = Ticking = Valid = FALSE;
- }
-
- IORawSerial::~IORawSerial()
- {
- Close();
- }
-
- VOID IORawSerial::StartTime(ULONG Seconds,ULONG Micros)
- {
- StopTime();
-
- TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
- TimeRequest->tr_time.tv_secs = Seconds;
- TimeRequest->tr_time.tv_micro = Micros;
-
- SetSignal(0,TimeMask);
-
- SendIO((struct IORequest *)TimeRequest);
-
- Ticking = TRUE;
- }
-
- VOID IORawSerial::StopTime(VOID)
- {
- if(Ticking)
- {
- if(!CheckIO((struct IORequest *)TimeRequest))
- AbortIO((struct IORequest *)TimeRequest);
-
- WaitTime();
- }
- }
-
- VOID IORawSerial::WaitTime(VOID)
- {
- if(Ticking)
- {
- WaitIO((struct IORequest *)TimeRequest);
-
- Ticking = FALSE;
- }
- }
-
- VOID IORawSerial::Flush(VOID)
- {
- if(Valid)
- {
- BOOL IsReading = Reading;
-
- StopRead();
-
- WriteRequest->IOSer.io_Command = CMD_CLEAR;
- DoIO((struct IORequest *)WriteRequest);
-
- if(IsReading)
- StartRead();
- }
- }
-